import os
import sys

from typing import Dict, Any, Optional

from backend.sdk.script_file import Script_file

from ..utils import logger

# 添加项目根目录到Python路径
current_dir = os.path.dirname(__file__)
project_root = os.path.dirname(os.path.dirname(os.path.dirname(current_dir)))
sys.path.insert(0, project_root)


# 文本类型的主要处理类，后续可以根据这个结构 生成其他的处理类，例如视频，音频，等


class TextConfigProcessor:
    """文本配置处理器"""

    @staticmethod
    def process(script: Script_file, text_conf: Dict[str, Any]):
        """处理文本配置，创建文本片段"""
        try:
            from sdk.track import Track_type
            # 解析基础参数
            basic_params = TextConfigProcessor._parse_basic_params(text_conf)

            # 解析样式参数
            text_style = TextConfigProcessor._parse_text_style(text_conf)

            # 解析描边和背景
            border = TextConfigProcessor._parse_border(text_conf)
            background = TextConfigProcessor._parse_background(text_conf)

            # 创建文本片段
            text_segment = TextConfigProcessor._create_text_segment(
                basic_params, text_style, border, background
            )

            # TODO 暂时不添加 处理特效和动画
            # TextEffectProcessor.apply_effects(text_segment, text_conf)
            TextAnimationProcessor.apply_animations(text_segment, text_conf)

            # 添加文本轨道和片段
            script.add_track(Track_type.text, "文本轨道")
            script.add_segment(text_segment, "文本轨道")

            return script

        except Exception as e:
            logger.error(f"处理文本配置失败: {e}")
            raise

    # 解析基本的参数 包含 文本内容、开始时间和持续时间等
    # 注意前端传递过来是 1000000 微秒（1秒） 前端需要进行转化为用户可以读取的形式 传递的时候 乘以1000000

    @staticmethod
    def _parse_basic_params(text_conf: Dict[str, Any]) -> Dict[str, Any]:
        """解析基础参数"""
        return {
            # 如果没有传递 就使用默认值
            'text': text_conf.get('text', '示例文本'),
            'start_time': text_conf.get('start_time', 0),
            'duration': text_conf.get('duration', 3000000)  # 默认3秒
        }

    # 文本样式参数 例如 字体大小、颜色、对齐方式等

    @staticmethod
    def _parse_text_style(text_conf: Dict[str, Any]):
        """解析文本样式"""
        from sdk.text_segment import Text_style

        style_data = text_conf.get('style', {})
        return Text_style(
            size=style_data.get('size', 8.0),
            bold=style_data.get('bold', False),
            italic=style_data.get('italic', False),
            underline=style_data.get('underline', False),
            color=tuple(style_data.get('color', [1.0, 1.0, 1.0])),
            alpha=style_data.get('alpha', 1.0),
            align=style_data.get('align', 1),
            vertical=style_data.get('vertical', False),
            letter_spacing=style_data.get('letter_spacing', 0),
            line_spacing=style_data.get('line_spacing', 0)
        )

    # 解析背景素材参数 包含背景视频的路径、名称和裁剪设置等
    @staticmethod
    def _parse_background_material(text_conf: Dict[str, Any]) -> Optional[Any]:
        """解析背景素材"""
        from sdk.local_materials import Video_material, Crop_settings

        background_material_data = text_conf.get('background_material')
        if not background_material_data:
            return None

        try:
            material_path = background_material_data.get('path')
            if not material_path:
                return None

            material_name = background_material_data.get('name', '背景素材')
            crop_data = background_material_data.get('crop_settings', {})

            crop_settings = Crop_settings(
                upper_left_x=crop_data.get('upper_left_x', 0.0),
                upper_left_y=crop_data.get('upper_left_y', 0.0),
                upper_right_x=crop_data.get('upper_right_x', 1.0),
                upper_right_y=crop_data.get('upper_right_y', 0.0),
                lower_left_x=crop_data.get('lower_left_x', 0.0),
                lower_left_y=crop_data.get('lower_left_y', 1.0),
                lower_right_x=crop_data.get('lower_right_x', 1.0),
                lower_right_y=crop_data.get('lower_right_y', 1.0)
            )

            background_material = Video_material(
                path=material_path,
                material_name=material_name,
                crop_settings=crop_settings
            )
            logger.info(f"成功创建背景素材: {background_material.material_name}")
            return background_material

        except Exception as e:
            logger.warning(f"创建背景素材失败: {e}")
            return None

    @staticmethod
    def _parse_border(text_conf: Dict[str, Any]) -> Optional[Any]:
        """解析描边参数"""
        from sdk.text_segment import Text_border

        border_data = text_conf.get('border')
        if not border_data:
            return None

        try:
            return Text_border(
                alpha=border_data.get('alpha', 1.0),
                color=tuple(border_data.get('color', [0.0, 0.0, 0.0])),
                width=border_data.get('width', 40.0)
            )
        except Exception as e:
            logger.warning(f"创建文本描边失败: {e}")
            return None

    @staticmethod
    def _parse_background(text_conf: Dict[str, Any]) -> Optional[Any]:
        """解析背景参数"""
        from sdk.text_segment import Text_background

        background_data = text_conf.get('background')
        if not background_data:
            return None

        try:
            return Text_background(
                color=background_data.get('color', '#000000'),
                style=background_data.get('style', 1),
                alpha=background_data.get('alpha', 1.0),
                round_radius=background_data.get('round_radius', 0.0),
                height=background_data.get('height', 0.14),
                width=background_data.get('width', 0.14),
                horizontal_offset=background_data.get(
                    'horizontal_offset', 0.5),
                vertical_offset=background_data.get('vertical_offset', 0.5)
            )
        except Exception as e:
            logger.warning(f"创建文本背景失败: {e}")
            return None

    @staticmethod
    def _create_text_segment(basic_params: Dict[str, Any], text_style, border, background):
        """创建文本片段"""
        from sdk.text_segment import Text_segment
        from sdk.time_util import Timerange

        timerange = Timerange(
            basic_params['start_time'], basic_params['duration'])

        return Text_segment(
            text=basic_params['text'],
            timerange=timerange,
            style=text_style,
            border=border,
            background=background
        )


# 文本特效的处理类，如果有文本特效处理出现问题 直接找这里
class TextEffectProcessor:
    """文本特效处理器"""

    @staticmethod
    def apply_effects(text_segment, text_conf: Dict[str, Any]):
        """应用文本特效（气泡、花字等）"""
        TextEffectProcessor._apply_bubble_effect(text_segment, text_conf)
        TextEffectProcessor._apply_fancy_text_effect(text_segment, text_conf)

    @staticmethod
    def _apply_bubble_effect(text_segment, text_conf: Dict[str, Any]):
        """应用气泡效果"""
        bubble_data = text_conf.get('bubble')
        if not bubble_data:
            return

        try:
            bubble_effect_id = bubble_data.get('effect_id')
            bubble_resource_id = bubble_data.get('resource_id')

            if bubble_effect_id and bubble_resource_id:
                if hasattr(text_segment, 'add_bubble'):
                    text_segment.add_bubble(
                        bubble_effect_id, bubble_resource_id)
                    logger.info(
                        f"成功添加气泡效果: effect_id={bubble_effect_id}, resource_id={bubble_resource_id}")
                else:
                    logger.warning("Text_segment 不支持 add_bubble 方法")
            else:
                logger.warning("气泡效果参数不完整，需要 effect_id 和 resource_id")
        except Exception as e:
            logger.warning(f"添加气泡效果失败: {e}")

    @staticmethod
    def _apply_fancy_text_effect(text_segment, text_conf: Dict[str, Any]):
        """应用花字效果"""
        fancy_text_data = text_conf.get('fancy_text')
        if not fancy_text_data:
            return

        try:
            fancy_effect_id = fancy_text_data.get('effect_id')
            if fancy_effect_id:
                if hasattr(text_segment, 'add_effect'):
                    text_segment.add_effect(fancy_effect_id)
                    logger.info(f"成功添加花字效果: effect_id={fancy_effect_id}")
                else:
                    logger.warning("Text_segment 不支持 add_effect 方法")
            else:
                logger.warning("花字效果参数不完整，需要 effect_id")
        except Exception as e:
            logger.warning(f"添加花字效果失败: {e}")

# 文本动画处理器 包含入场、出场和循环动画的处理逻辑


class TextAnimationProcessor:
    """文本动画处理器"""

    @staticmethod
    def apply_animations(text_segment, text_conf: Dict[str, Any]):
        """应用文本动画效果"""
        animations_data = text_conf.get('animations', {})
        intro_animation = animations_data.get('intro')
        outro_animation = animations_data.get('outro')
        loop_animation = animations_data.get('loop')

        if not any([intro_animation, outro_animation, loop_animation]):
            return

        try:
            from sdk.metadata.animation_meta import Text_intro, Text_outro, Text_loop_anim

            # 添加入场动画
            if intro_animation:
                TextAnimationProcessor._add_intro_animation(
                    text_segment, intro_animation, Text_intro)

            # 添加出场动画
            if outro_animation:
                TextAnimationProcessor._add_outro_animation(
                    text_segment, outro_animation, Text_outro)

            # 添加循环动画
            if loop_animation:
                TextAnimationProcessor._add_loop_animation(
                    text_segment, loop_animation, Text_loop_anim)

        except (ImportError, AttributeError) as e:
            logger.warning(f"动画功能不可用: {e}")

    @staticmethod
    def _add_intro_animation(text_segment, intro_animation: Dict[str, Any], Text_intro):
        """添加入场动画"""
        anim_type = intro_animation.get('type')
        anim_duration = intro_animation.get('duration', 500000)

        if not anim_type:
            logger.warning("入场动画参数不完整，需要 type")
            return

        if hasattr(Text_intro, anim_type) and hasattr(text_segment, 'add_animation'):
            animation_meta = getattr(Text_intro, anim_type)
            text_segment.add_animation(animation_meta, anim_duration)
            logger.info(f"成功添加入场动画: {anim_type}, 持续时间: {anim_duration}微秒")
        else:
            logger.warning(f"不支持的入场动画类型: {anim_type} 或 Text_segment 不支持动画")

    @staticmethod
    def _add_outro_animation(text_segment, outro_animation: Dict[str, Any], Text_outro):
        """添加出场动画"""
        anim_type = outro_animation.get('type')
        anim_duration = outro_animation.get('duration', 500000)

        if not anim_type:
            logger.warning("出场动画参数不完整，需要 type")
            return

        if hasattr(Text_outro, anim_type) and hasattr(text_segment, 'add_animation'):
            animation_meta = getattr(Text_outro, anim_type)
            text_segment.add_animation(animation_meta, anim_duration)
            logger.info(f"成功添加出场动画: {anim_type}, 持续时间: {anim_duration}微秒")
        else:
            logger.warning(f"不支持的出场动画类型: {anim_type} 或 Text_segment 不支持动画")

    @staticmethod
    def _add_loop_animation(text_segment, loop_animation: Dict[str, Any], Text_loop_anim):
        """添加循环动画"""
        anim_type = loop_animation.get('type')

        if not anim_type:
            logger.warning("循环动画参数不完整，需要 type")
            return

        if hasattr(Text_loop_anim, anim_type) and hasattr(text_segment, 'add_animation'):
            animation_meta = getattr(Text_loop_anim, anim_type)
            text_segment.add_animation(animation_meta)
            logger.info(f"成功添加循环动画: {anim_type}")
        else:
            logger.warning(f"不支持的循环动画类型: {anim_type} 或 Text_segment 不支持动画")


class TextResponseBuilder:
    """文本响应构建器"""

    @staticmethod
    def build_text_response_info(text_conf: Dict[str, Any]) -> Dict[str, Any]:
        """构建文本配置的响应信息"""
        style_data = text_conf.get('style', {})
        animations_data = text_conf.get('animations', {})

        # 构建响应中的效果信息
        effects_info = TextResponseBuilder._build_effects_info(
            text_conf, animations_data)

        return {
            "text": text_conf.get('text', '示例文本'),
            "style": {
                "size": style_data.get('size', 8.0),
                "bold": style_data.get('bold', False),
                "italic": style_data.get('italic', False),
                "underline": style_data.get('underline', False),
                "color": style_data.get('color', [1.0, 1.0, 1.0]),
                "alpha": style_data.get('alpha', 1.0),
                "align": style_data.get('align', 1),
                "vertical": style_data.get('vertical', False),
                "letter_spacing": style_data.get('letter_spacing', 0),
                "line_spacing": style_data.get('line_spacing', 0)
            },
            "effects": effects_info
        }

    @staticmethod
    def _build_effects_info(text_conf: Dict[str, Any], animations_data: Dict[str, Any]) -> Dict[str, Any]:
        """构建效果信息"""
        effects_info = {}

        # 气泡效果
        bubble_data = text_conf.get('bubble')
        if bubble_data and bubble_data.get('effect_id') and bubble_data.get('resource_id'):
            effects_info['bubble'] = {
                'effect_id': bubble_data.get('effect_id'),
                'resource_id': bubble_data.get('resource_id')
            }

        # 花字效果
        fancy_text_data = text_conf.get('fancy_text')
        if fancy_text_data and fancy_text_data.get('effect_id'):
            effects_info['fancy_text'] = {
                'effect_id': fancy_text_data.get('effect_id')
            }

        # 动画效果
        intro_animation = animations_data.get('intro')
        outro_animation = animations_data.get('outro')
        loop_animation = animations_data.get('loop')

        if intro_animation or outro_animation or loop_animation:
            effects_info['animations'] = {}
            if intro_animation and intro_animation.get('type'):
                effects_info['animations']['intro'] = intro_animation
            if outro_animation and outro_animation.get('type'):
                effects_info['animations']['outro'] = outro_animation
            if loop_animation and loop_animation.get('type'):
                effects_info['animations']['loop'] = loop_animation

        return effects_info
